package Reflection;

import java.lang.reflect.Field;

/**
 * 获取字段的方法:
    getField(name) 根据字段名获取某个public的字段对象，包括父类中的字段。
    getDeclaredField(name) 根据字段名获取当前类的某个field，不包括父类中的字段。
    getFields() 获取当前类的所有public的字段，包括父类中的字段。
    getDeclaredFields() 获取当前类的所有field，不包括父类中的字段。

  一个Field对象包含以下信息：
    getName() 获取字段名
    getType() 获取字段类型
    getModifiers() 获取字段的修饰符
    get(obj) 获取字段的值
    set(obj, value) 设置字段的值

   注意：
   1. 对于private字段，只能通过getDeclaredField()方法获取。
   2. 对于protected字段，只能通过getField()方法获取。
 */
public class FieldDemo {
  public static void main(String[] args) {
    Class stdClass = Student.class;
    try {
      System.out.println("Field of Student class: " + stdClass.getField("score"));
      System.out.println("Field of Student class: " + stdClass.getField("name"));
      System.out.println("Field of Student class: " + stdClass.getDeclaredField("grade"));

      System.out.println("Fields of Student class: " + stdClass.getFields().length);
      System.out.println("Fields of Student class: " + stdClass.getDeclaredFields().length);

      System.out.println("Field of Student getName: " + stdClass.getField("name").getName());
      System.out.println("Field of Student getType: " + stdClass.getField("name").getType());
      System.out.println("Field of Student getModifiers: " + stdClass.getField("name").getModifiers());

      Object p = new Person("xiao ming");
      Class c = p.getClass();
      Field f = c.getDeclaredField("name");
      f.set(p, "Xiao Hong");
      Object value = f.get(p);
      System.out.println("value of Person name: " + value);
    } catch (NoSuchFieldException e) {
      System.out.println("Field not found: " + e.getMessage());
    } catch (IllegalAccessException e) {
      System.out.println("Field can not access: " + e.getMessage());
    }
  }
}

class Person {
  public String name;
  public Person(String name) {
    this.name = name;
  }
}
class Student extends Person {
  public int score;
  private int grade;

  public Student(String name, int score) {
    super(name);
    this.score = score;
    }
}